/****************************************************
          File Name:list.c
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Wed 15 Oct 2014 06:04:36 PM CST
*****************************************************/

#include "list.h"

Node *lcreate(int range)
{
    Node *root = NULL, *cur, *pre;
    int input;

    if(range == 0)
    {
        printf("initailized an empty list\n");
        return root;
    }
    while(range-- > 0)
    {
        cur = (Node *)malloc(sizeof(Node));
        if(cur == NULL)
            return (Node *)-1;
        if(root == NULL)
            root = cur;
        else
            pre->link = cur;
        printf("enter element: ");
        scanf("%d",&input);
        cur->number=input;
        cur->link = NULL;
        pre = cur;
        if(range == 1)
            printf("\e[31mone element left\e[0m\n");
    }

    cur = root;
    return cur;
}

/* count start from 0 , NOT 1 !!! */
int modify(Node *head,int where,int new_value)
{
	Node *cur;
	cur = head;
	
	while(cur != NULL && where--)
		cur = cur->link;
	
	cur->number = new_value;
	return 0;
}
	
int isInlist(Node *head, int new_value)
{
	Node *cur;
	cur = head;
	
	while(cur != NULL)
	{
		if(cur->number == new_value)
			break;
		cur=cur->link;
	}
	
	if(cur == NULL)
		return 0; 			/* not in list */
	else
	{
		errno = EEXIST;
		return -1;			/* in list */
	}
}

/*  注释掉的是以前的冗余代码, 已经不能再精简了  ; count from 0 NOT 1 !!!*/
int insert(Node **linkd, int where)
{
    Node *cur, *pre, *new;

   // cur = *linkd;
   // pre = NULL;

/* must judge if cur eq NULL before judging cur->name lt  where */
   // while(cur != NULL && cur->number < where) 
   while((cur = *linkd) != NULL && cur->number < where)
    {
       // pre = cur;
        //cur = cur->link;
		linkd = &cur->link;
    }

    new = (Node *)malloc(sizeof(Node));
    if(new == NULL)
        return -1;

    new->number = where;
    new->link=cur;

    /*
	if(pre == NULL)
        *linkd = new;
	else
        pre->link = new;
	*/
	
	*linkd = new;
    return 0;
}

int delete(Node **linkd, int where) 
{
    Node *cur, *pre;

    cur = *linkd;
    pre = NULL;

	if(cur != NULL && cur->number == where) /* delete head Node */
    {
	    cur = cur->link;
	    *linkd = cur;
        free(cur);
	    return 0;
    }

    while(cur !=NULL && cur->number != where)
    {
        pre = cur;
        cur = cur->link;
    }

    if(cur == NULL)
	{
		errno = EINVAL;
        return -1;
	}

    pre->link = cur->link;
    free(cur);
    return 0;
}

int show(Node *head)
{
    Node *cur;
    cur = head;
    while(cur != NULL)
    {
        printf("name : %d\n",cur->number);
        cur = cur->link;
    }
    return 0;
}

int len(Node *head)
{
    Node *cur;
    int len = 0;
    cur = head;
    while(cur != NULL)
    {
        len++;
        cur = cur->link;
    }

    return len;
}

/* option: 'l2s': large to small; 's2l': small to large.*/
Node *lrank(Node *head, char *option)
{
    Node *p, *n; /* previous , next */
    Node *cur, *pre, *ne; /* current, previous, next */
    int tmp;

    for(p= head; p != NULL; p = p->link)
    {
        for(n = p->link; n != NULL; n = n->link)
        {
            if(p->number > n->number)
            {
                tmp = n->number;
                n->number = p->number;
                p->number = tmp;
            }
        }
    }
    if(strcmp(option,"l2s") == 0)
    {
        pre = head;
        cur = head->link;
        
        while(cur)
        {
            ne = cur->link;
            cur->link = pre;
            pre = cur;
            cur = ne;
        }
        head->link = NULL;
        head = pre;
    }

    return head;
}

/* find element , useless for only one element in a list */
/* not test yet */
Node *lfind(Node *head, int number)
{
    Node *cur, *out=NULL;
    cur = head;

    while(cur != NULL)
    {
        if(number == cur->number)
        {
            out =  malloc(sizeof(Node));
            out = cur;
            break;
        }
        cur = cur->link;
    }
    return out;
}
int destroy(Node *head)
{
    while(head != NULL)
    {
        free(head);
        head = head->link;
    }
    return 0;
}

